home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / pibt40s2.arc / PIB4010A.MOD < prev    next >
Text File  |  1987-05-25  |  51KB  |  866 lines

  1. PROCEDURE Emulate_TEK4010;
  2.  
  3. (*----------------------------------------------------------------------*)
  4. (*             Emulate_TEK4010 --- Emulate TekTronix 4010 terminal      *)
  5. (*----------------------------------------------------------------------*)
  6. (*                                                                      *)
  7. (*  Author:  Philip R. Burns                                            *)
  8. (*  Date:    April, 1986        (Version 1.0)                           *)
  9. (*           November, 1986     (Version 2.0 -- EGA support)            *)
  10. (*           February, 1987     (Version 2.1 -- fix minor bugs          *)
  11. (*           March, 1987        (Version 2.2 -- speed up display        *)
  12. (*                                                                      *)
  13. (*  Systems: For MS-DOS on IBM PCs and close compatibles only.          *)
  14. (*                                                                      *)
  15. (*  History: Original with me.                                          *)
  16. (*                                                                      *)
  17. (*           This emulator uses the high-resolution graphics mode       *)
  18. (*           (640x200) of the standard IBM color graphics adapter.      *)
  19. (*           Only graphics output is emulated, not graphics input.      *)
  20. (*           The display consists of 33 rather than 35 lines of text,   *)
  21. (*           because of the limited display resolution available on the *)
  22. (*           PC.                                                        *)
  23. (*                                                                      *)
  24. (*           Suggestions for improvements or corrections are welcome.   *)
  25. (*           Please leave messages on Gene Plantz's BBS (312) 882 4145  *)
  26. (*           or Ron Fox's BBS (312) 940 6496.                           *)
  27. (*                                                                      *)
  28. (*           IF you use this code in your own programs, please be nice  *)
  29. (*           and give proper credit.                                    *)
  30. (*                                                                      *)
  31. (*----------------------------------------------------------------------*)
  32.  
  33. TYPE
  34.    Graphics_State = ( Text_Plot, Vector_Plot_Start, Vector_Plot,
  35.                       Point_Plot_Start, Point_Plot, Graphics_Input );
  36.  
  37. VAR
  38.    Done       : BOOLEAN            (* TRUE to exit terminal emulation mode *);
  39.    Ch         : CHAR               (* Character read/written               *);
  40.    B          : BOOLEAN            (* Boolean flag                         *);
  41.    Regs       : RegPack            (* For MS DOS interfacing               *);
  42.    FlagG      : Graphics_State     (* Current graphics state               *);
  43.    CursorX    : INTEGER            (* X position of cursor                 *);
  44.    CursorY    : INTEGER            (* Y position of cursor                 *);
  45.    Reset_T    : BOOLEAN            (* Dummy for reset of terminal          *);
  46.    EGA_On     : BOOLEAN            (* TRUE if EGA installed                *);
  47.    XFactor    : REAL               (* Horizontal scaling factor            *);
  48.    YFactor    : REAL               (* Vertical scaling factor              *);
  49.    YMax       : INTEGER            (* Maximum Y value ==> 199, 349         *);
  50.    YMaxM1     : INTEGER            (* Maximum Y value - 1 ==> 198, 348     *);
  51.    YInc       : INTEGER            (* Increment in Y for characters        *);
  52.    GMode      : INTEGER            (* Graphics mode type                   *);
  53.    ClrScr_Req : BOOLEAN            (* TRUE if clear screen request typed   *);
  54.    Save_SUpper: BOOLEAN            (* Save send_upper_case_only flag       *);
  55.  
  56. CONST
  57.    Prev_Ch : CHAR = ^@;
  58.    Hx      : INTEGER = 0;
  59.    Hy      : INTEGER = 0;
  60.    Lx      : INTEGER = 0;
  61.    Ly      : INTEGER = 0;
  62.    Old     : INTEGER = 0;
  63.    LeftH   : BOOLEAN = TRUE;
  64.    LastX   : INTEGER = 0;
  65.    LastY   : INTEGER = 0;
  66.  
  67. CONST
  68.    Ch_FF   = #12                   (* Form Feed       *);
  69.    Ch_CR   = #13                   (* Carriage Return *);
  70.    Ch_SO   = #14                   (* Start grahics   *);
  71.    Ch_SI   = #15                   (* End graphics    *);
  72.    Ch_SUB  = #26                   (* EOF Character   *);
  73.    Ch_ESC  = #27                   (* Escape          *);
  74.    Ch_FS   = #28                   (* Graphics start  *);
  75.    Ch_GS   = #29                   (* Graphics start  *);
  76.    Ch_RS   = #30                   (* Inc. plot start *);
  77.    Ch_US   = #31                   (* Graphics end    *);
  78.  
  79. (* STRUCTURED *) CONST             (* Starting bytes for each CGA scan line *)
  80.    Scan_Line_Table : ARRAY[0..199] OF INTEGER =
  81.                      (    0,  8192,   80,  8272,  160,  8352,  240,  8432,
  82.                         320,  8512,  400,  8592,  480,  8672,  560,  8752,
  83.                         640,  8832,  720,  8912,  800,  8992,  880,  9072,
  84.                         960,  9152, 1040,  9232, 1120,  9312, 1200,  9392,
  85.                        1280,  9472, 1360,  9552, 1440,  9632, 1520,  9712,
  86.                        1600,  9792, 1680,  9872, 1760,  9952, 1840, 10032,
  87.                        1920, 10112, 2000, 10192, 2080, 10272, 2160, 10352,
  88.                        2240, 10432, 2320, 10512, 2400, 10592, 2480, 10672,
  89.                        2560, 10752, 2640, 10832, 2720, 10912, 2800, 10992,
  90.                        2880, 11072, 2960, 11152, 3040, 11232, 3120, 11312,
  91.                        3200, 11392, 3280, 11472, 3360, 11552, 3440, 11632,
  92.                        3520, 11712, 3600, 11792, 3680, 11872, 3760, 11952,
  93.                        3840, 12032, 3920, 12112, 4000, 12192, 4080, 12272,
  94.                        4160, 12352, 4240, 12432, 4320, 12512, 4400, 12592,
  95.                        4480, 12672, 4560, 12752, 4640, 12832, 4720, 12912,
  96.                        4800, 12992, 4880, 13072, 4960, 13152, 5040, 13232,
  97.                        5120, 13312, 5200, 13392, 5280, 13472, 5360, 13552,
  98.                        5440, 13632, 5520, 13712, 5600, 13792, 5680, 13872,
  99.                        5760, 13952, 5840, 14032, 5920, 14112, 6000, 14192,
  100.                        6080, 14272, 6160, 14352, 6240, 14432, 6320, 14512,
  101.                        6400, 14592, 6480, 14672, 6560, 14752, 6640, 14832,
  102.                        6720, 14912, 6800, 14992, 6880, 15072, 6960, 15152,
  103.                        7040, 15232, 7120, 15312, 7200, 15392, 7280, 15472,
  104.                        7360, 15552, 7440, 15632, 7520, 15712, 7600, 15792,
  105.                        7680, 15872, 7760, 15952, 7840, 16032, 7920, 16112  );
  106.  
  107. (*----------------------------------------------------------------------*)
  108. (*         Plot_Point --- Plot one point in graphics display            *)
  109. (*----------------------------------------------------------------------*)
  110.  
  111. PROCEDURE Plot_Point( X , Y: INTEGER );
  112.  
  113. (*----------------------------------------------------------------------*)
  114. (*                                                                      *)
  115. (*     Procedure:  Plot_Point                                           *)
  116. (*                                                                      *)
  117. (*     Purpose:    Plots one pixel in high-resolution graphics screen.  *)
  118. (*                                                                      *)
  119. (*     Calling Sequence:                                                *)
  120. (*                                                                      *)
  121. (*        Plot_Point( X , Y : INTEGER );                                *)
  122. (*                                                                      *)
  123. (*           X --- Horizontal coordinate (0--639)                       *)
  124. (*           Y --- Vertical coordinate   (0--199)                       *)
  125. (*                                                                      *)
  126. (*----------------------------------------------------------------------*)
  127.  
  128. BEGIN (* Plot_Point *)
  129.  
  130. INLINE(
  131.                                   {;}
  132.                                   {;  Check if we are to use BIOS to plot pixel}
  133.                                   {;}
  134.   $F6/$06/>WRITE_SCREEN_MEMORY/$01{         TEST    Byte [>Write_Screen_Memory],1 ;Check if direct scren writes}
  135.   /$74/$31                        {         JZ      Bios                       ;No -- use BIOS}
  136.                                   {;}
  137.                                   {;  Write pixel directly to screen memory}
  138.                                   {;}
  139.   /$8B/$96/>Y                     {         MOV     DX,[BP+>Y]            ; Get Y}
  140.   /$8D/$1E/>SCAN_LINE_TABLE       {         LEA     BX,[>Scan_Line_Table] ; Get scan line table address}
  141.   /$D1/$E2                        {         SHL     DX,1                  ; Y * 2 for integer offset}
  142.   /$01/$D3                        {         ADD     BX,DX                 ; Get offset of entry for Y}
  143.   /$2E/$8B/$1F                    {     CS: MOV     BX,[BX]               ; Get offset for Y}
  144.                                   {;}
  145.   /$8B/$96/>X                     {         MOV     DX,[BP+>X]            ; Get X}
  146.   /$89/$D0                        {         MOV     AX,DX}
  147.   /$B1/$03                        {         MOV     CL,3                  ;}
  148.   /$D3/$EA                        {         SHR     DX,CL                 ; X DIV 8 = Byte offset within row}
  149.   /$01/$D3                        {         ADD     BX,DX                 ; Byte location in screen memory}
  150.   /$25/$07/$00                    {         AND     AX,7                  ; X MOD 8}
  151.   /$BA/$80/$00                    {         MOV     DX,$80                ; 1 bit in leftmost position}
  152.   /$89/$C1                        {         MOV     CX,AX                 ; shift count}
  153.   /$D3/$EA                        {         SHR     DX,CL                 ; 1 bit in proper position}
  154.   /$C4/$3E/>GRAPHICS_SCREEN       {         LES     DI,[>Graphics_Screen] ; Get screen address}
  155.   /$01/$DF                        {         ADD     DI,BX                 ; Get byte address}
  156.   /$26/$08/$15                    {     ES: OR      BYTE PTR [DI],DL      ; Get byte to alter}
  157.   /$E9/$0F/$00                    {         JMP     Exit                  ; Return to caller}
  158.                                   {;}
  159.                                   {;  Plot pixel using BIOS}
  160.                                   {;}
  161.   /$55                            {Bios:    PUSH    BP                    ; Save BP in case BIOS zaps it}
  162.   /$B8/$01/$0C                    {         MOV     AX,$0C01              ; Plot pixel function}
  163.   /$8B/$8E/>X                     {         MOV     CX,[BP+>X]            ; Get horizontal position}
  164.   /$8B/$96/>Y                     {         MOV     DX,[BP+>Y]            ; Get vertical position}
  165.   /$CD/$10                        {         INT     $10                   ; Plot the pixel via BIOS}
  166.   /$5D                            {         POP     BP                    ; Restore BP}
  167.                                   {;}
  168.                                   {Exit:}
  169. );
  170.  
  171. END   (* Plot_Point *);
  172.  
  173. (*----------------------------------------------------------------------*)
  174. (*  XOR_Plot_Point --- Plot one point in graphics display using XOR     *)
  175. (*----------------------------------------------------------------------*)
  176.  
  177. PROCEDURE XOR_Plot_Point( X , Y: INTEGER );
  178.  
  179. (*----------------------------------------------------------------------*)
  180. (*                                                                      *)
  181. (*     Procedure:  XOR_Plot_Point                                       *)
  182. (*                                                                      *)
  183. (*     Purpose:    Plots one pixel in high-res graphics using XOR.      *)
  184. (*                                                                      *)
  185. (*     Calling Sequence:                                                *)
  186. (*                                                                      *)
  187. (*        XOR_Plot_Point( X , Y : INTEGER );                            *)
  188. (*                                                                      *)
  189. (*           X --- Horizontal coordinate (0--639)                       *)
  190. (*           Y --- Vertical coordinate   (0--199)                       *)
  191. (*                                                                      *)
  192. (*----------------------------------------------------------------------*)
  193.  
  194. BEGIN (* XOR_Plot_Point *)
  195.  
  196. INLINE(
  197.                                   {;}
  198.                                   {;  Check if we are to use BIOS to plot pixel}
  199.                                   {;}
  200.   $F6/$06/>WRITE_SCREEN_MEMORY/$01{         TEST    Byte [>Write_Screen_Memory],1 ;Check if direct scren writes}
  201.   /$74/$31                        {         JZ      Bios                       ;No -- use BIOS}
  202.                                   {;}
  203.                                   {;  XOR pixel directly to screen memory}
  204.                                   {;}
  205.   /$8B/$96/>Y                     {         MOV     DX,[BP+>Y]            ; Get Y}
  206.   /$8D/$1E/>SCAN_LINE_TABLE       {         LEA     BX,[>Scan_Line_Table] ; Get scan line table address}
  207.   /$D1/$E2                        {         SHL     DX,1                  ; Y * 2 for integer offset}
  208.   /$01/$D3                        {         ADD     BX,DX                 ; Get offset of entry for Y}
  209.   /$2E/$8B/$1F                    {     CS: MOV     BX,[BX]               ; Get offset for Y}
  210.                                   {;}
  211.   /$8B/$96/>X                     {         MOV     DX,[BP+>X]            ; Get X}
  212.   /$89/$D0                        {         MOV     AX,DX}
  213.   /$B1/$03                        {         MOV     CL,3                  ;}
  214.   /$D3/$EA                        {         SHR     DX,CL                 ; X DIV 8 = Byte offset within row}
  215.   /$01/$D3                        {         ADD     BX,DX                 ; Byte location in screen memory}
  216.   /$25/$07/$00                    {         AND     AX,7                  ; X MOD 8}
  217.   /$BA/$80/$00                    {         MOV     DX,$80                ; 1 bit in leftmost position}
  218.   /$89/$C1                        {         MOV     CX,AX                 ; shift count}
  219.   /$D3/$EA                        {         SHR     DX,CL                 ; 1 bit in proper position}
  220.   /$C4/$3E/>GRAPHICS_SCREEN       {         LES     DI,[>Graphics_Screen] ; Get screen address}
  221.   /$01/$DF                        {         ADD     DI,BX                 ; Get byte address}
  222.   /$26/$30/$15                    {     ES: XOR     BYTE PTR [DI],DL      ; Get byte to alter}
  223.   /$E9/$0F/$00                    {         JMP     Exit                  ; Return to caller}
  224.                                   {;}
  225.                                   {;  Plot pixel using BIOS}
  226.                                   {;}
  227.   /$55                            {Bios:    PUSH    BP                    ; Save BP in case BIOS zaps it}
  228.   /$B8/$81/$0C                    {         MOV     AX,$0C81              ; Plot pixel function using XOR}
  229.   /$8B/$8E/>X                     {         MOV     CX,[BP+>X]            ; Get horizontal position}
  230.   /$8B/$96/>Y                     {         MOV     DX,[BP+>Y]            ; Get vertical position}
  231.   /$CD/$10                        {         INT     $10                   ; Plot the pixel via BIOS}
  232.   /$5D                            {         POP     BP                    ; Restore BP}
  233.                                   {;}
  234.                                   {Exit:}
  235. );
  236.  
  237. END   (* XOR_Plot_Point *);
  238.  
  239. (*----------------------------------------------------------------------*)
  240. (*          Clear_Graphics_Screen --- Clear screen and home cursor      *)
  241. (*----------------------------------------------------------------------*)
  242.  
  243. PROCEDURE Clear_Graphics_Screen;
  244.  
  245. VAR
  246.    Regs    : RegPack               (* For MS DOS interfacing        *);
  247.  
  248. BEGIN (* Clear_Graphics_Screen *)
  249.  
  250.    Set_Graphics_Colors( EGA_On, GMode,
  251.                         Graphics_Foreground_Color, Graphics_BackGround_Color );
  252.  
  253.                                    (* Move cursor to upper left-hand *)
  254.                                    (* cursor.                        *)
  255.    Graphics_XPos := 0;
  256.    Graphics_YPos := 5;
  257.  
  258.    CursorX       := 0;
  259.    CursorY       := 5;
  260.  
  261.    LeftH         := TRUE;
  262.    Prev_Ch       := CHR( 0 );
  263.  
  264. END   (* Clear_Graphics_Screen *);
  265.  
  266. (*--------------------------------------------------------------------------*)
  267. (*           Draw_Line -- Draw line between two points, low res. mode      *)
  268. (*--------------------------------------------------------------------------*)
  269.  
  270. PROCEDURE Draw_Line( X1, Y1, X2, Y2: INTEGER );
  271.  
  272. (*--------------------------------------------------------------------------*)
  273. (*                                                                          *)
  274. (*    Procedure:  Draw_Line                                                 *)
  275. (*                                                                          *)
  276. (*    Purpose:    Draws line between two points in hi-res. graphics mode    *)
  277. (*                                                                          *)
  278. (*    Calling Sequence:                                                     *)
  279. (*                                                                          *)
  280. (*       Draw_Line( X1 , Y1 , X2, Y2, LineCol : INTEGER );                  *)
  281. (*                                                                          *)
  282. (*           X1      -- Horizontal postion (0 through 639), 1st point       *)
  283. (*           Y1      -- Vertical position (0 through 119), 1st point        *)
  284. (*           X2      -- Horizontal postion (0 through 639), 2nd point       *)
  285. (*           Y2      -- Vertical position (0 through 119), 2nd point        *)
  286. (*                                                                          *)
  287. (*    Calls:  TurnOnTimeSharing                                             *)
  288. (*            TurnOffTimeSharing                                            *)
  289. (*            Get_Screen_Address                                            *)
  290. (*                                                                          *)
  291. (*    Remarks: An incremental plotter algorithm is used.                    *)
  292. (*                                                                          *)
  293. (*--------------------------------------------------------------------------*)
  294.  
  295. VAR
  296.    LongDelta : INTEGER;
  297.    LongStep  : INTEGER;
  298.    ShortStep : INTEGER;
  299.    LineStart : INTEGER;
  300.    LineStop  : INTEGER;
  301.  
  302. BEGIN (* Draw_Line *)
  303.                                    (* Turn off timesharing while drawing *)
  304.  
  305.    IF ( MultiTasker = DoubleDos ) THEN
  306.       BEGIN
  307.          TurnOffTimeSharing;
  308.          Get_Screen_Address( Graphics_Screen );
  309.       END;
  310.  
  311. INLINE(
  312.   $C7/$86/>LONGSTEP/$01/$00        {          MOV    WORD PTR >LongStep[BP],1       ; assume motion down or right}
  313.   /$8B/$B6/>X2                     {          MOV    SI,>X2[BP]}
  314.   /$2B/$B6/>X1                     {          SUB    SI,>X1[BP]                     ; get BP := LongDelta}
  315.   /$7D/$06                         {          JGE    PL1                            ; if X1 <= X2 then no change}
  316.   /$F7/$9E/>LONGSTEP               {          NEG    WORD PTR >LongStep[BP]         ; ELSE LongStep := -1 (motion up or left)}
  317.   /$F7/$DE                         {          NEG    SI                             ;       LongDelta = abs(LongDelta)}
  318.                                    {PL1:}
  319.   /$C7/$86/>SHORTSTEP/$01/$00      {          MOV    WORD PTR >ShortStep[BP],1      ; assume motion down or right}
  320.   /$8B/$86/>Y2                     {          MOV    AX,>Y2[BP]}
  321.   /$2B/$86/>Y1                     {          SUB    AX,>Y1[BP]                     ; get AX := shortdelta}
  322.   /$7D/$06                         {          JGE    PL2                            ; if y1 <= y2 then no change}
  323.   /$F7/$9E/>SHORTSTEP              {          NEG    WORD PTR >ShortStep[BP]        ; else, ShortStep = -1 (motion up or left)}
  324.   /$F7/$D8                         {          NEG    AX                             ;       shortdelta = abs(shortdelta)}
  325.                                    {PL2:}
  326.   /$C7/$86/>LINESTART/$00/$00      {          MOV    WORD PTR >LineStart[BP],0      ; assume no skip length}
  327.   /$8B/$8E/>X1                     {          MOV    CX,>X1[BP]                     ; x coordinate in CX}
  328.   /$8B/$96/>Y1                     {          MOV    DX,>Y1[BP]                     ; y coordinate in DX}
  329.   /$39/$F0                         {          CMP    AX,SI                          ; is shortdelta longer than LongDelta?}
  330.   /$77/$40                         {          JA     AltCode                        ; yes, use alternate drawing code}
  331.                                    {;}
  332.                                    {;         Do following when line has slope between 0 and 1}
  333.                                    {;}
  334.   /$89/$B6/>LINESTOP               {          MOV    >LineStop[BP],SI               ; assume length = LongDelta}
  335.   /$89/$F7                         {          MOV    DI,SI                          ; set up the cycle pointer}
  336.   /$D1/$EF                         {          SHR    DI,1                           ; cycle := LongDelta/2}
  337.   /$89/$B6/>LONGDELTA              {          MOV    >LongDelta[BP],SI}
  338.   /$BE/$00/$00                     {          MOV    SI,0                           ; initialize loop counter}
  339.                                    {NormLoop:}
  340.   /$3B/$B6/>LINESTART              {          CMP    SI,>LineStart[BP]              ; start to plot yet???}
  341.   /$7C/$0D                         {          JL     PL5                            ; no, skip}
  342.                                    {;}
  343.   /$50                             {          PUSH   AX                             ;Save registers}
  344.   /$53                             {          PUSH   BX}
  345.   /$51                             {          PUSH   CX}
  346.   /$52                             {          PUSH   DX}
  347.   /$57                             {          PUSH   DI}
  348.                                    {;}
  349.   /$E8/$6E/$00                     {          CALL   PlotDot                        ;Plot pixel}
  350.                                    {;}
  351.   /$5F                             {          POP    DI                             ;Restore registers}
  352.   /$5A                             {          POP    DX}
  353.   /$59                             {          POP    CX}
  354.   /$5B                             {          POP    BX}
  355.   /$58                             {          POP    AX}
  356.                                    {;}
  357.                                    {PL5:}
  358.   /$03/$8E/>LONGSTEP               {          ADD    CX,>LongStep[BP]                ; always move along the X AXis}
  359.   /$01/$C7                         {          ADD    DI,AX                           ; cycle = cycle + shortdelta}
  360.   /$3B/$BE/>LONGDELTA              {          CMP    DI,>LongDelta[BP]               ; is cycle >= LongDelta?}
  361.   /$7C/$08                         {          JL     PL6                              ; no skip (don't move along y AXis yet}
  362.   /$2B/$BE/>LONGDELTA              {          SUB    DI,>LongDelta[BP]               ; yes, reset cycle pointer}
  363.   /$03/$96/>SHORTSTEP              {          ADD    DX,>ShortStep[BP]               ;       and bump the y coordinate}
  364.                                    {PL6:}
  365.   /$46                             {          INC    SI                             ; bump dot counter}
  366.   /$3B/$B6/>LINESTOP               {          CMP    SI,>LineStop[BP]               ; done??}
  367.   /$76/$D2                         {          JBE    NormLoop                       ; no, plot next dot}
  368.   /$E9/$85/$00                     {          JMP    PLExit                         ; yes, go to commom exit code}
  369.                                    {;}
  370.                                    {;         Do following when slope has absolute value > 1}
  371.                                    {;}
  372.                                    {AltCode:}
  373.   /$96                             {          XCHG   AX,SI                         ; swap LongDelta, shortdelta}
  374.   /$8B/$BE/>LONGSTEP               {          MOV    DI,>LongStep[BP]              ;}
  375.   /$87/$BE/>SHORTSTEP              {          XCHG   >ShortStep[BP],DI}
  376.   /$89/$BE/>LONGSTEP               {          MOV    >LongStep[BP],DI              ; swap LongStep, ShortStep}
  377.   /$89/$B6/>LINESTOP               {          MOV    >LineStop[BP],SI              ; assume length = LongDelta}
  378.   /$89/$F7                         {          MOV    DI,SI                         ; set up cycle pointer}
  379.   /$D1/$EF                         {          SHR    DI,1                          ; cycle := LongDelta/2}
  380.   /$89/$B6/>LONGDELTA              {          MOV    >LongDelta[BP],SI}
  381.   /$BE/$00/$00                     {          MOV    SI,0                          ; initialize loop counter}
  382.                                    {AltLoop:}
  383.   /$3B/$B6/>LINESTART              {          CMP    SI,>LineStart[BP]             ; start to plot yet?}
  384.   /$7C/$0B                         {          JL     PL8                           ; no, skip}
  385.                                    {;}
  386.   /$50                             {          PUSH   AX                             ;Save registers}
  387.   /$51                             {          PUSH   CX}
  388.   /$52                             {          PUSH   DX}
  389.   /$57                             {          PUSH   DI}
  390.                                    {;}
  391.   /$E8/$22/$00                     {          CALL   PlotDot                        ;Plot pixel}
  392.                                    {;}
  393.   /$5F                             {          POP    DI                             ;Restore registers}
  394.   /$5A                             {          POP    DX}
  395.   /$59                             {          POP    CX}
  396.   /$58                             {          POP    AX}
  397.                                    {;}
  398.                                    {PL8:}
  399.   /$03/$96/>LONGSTEP               {          ADD    DX,>LongStep[BP]              ; always move along Y AXis}
  400.   /$01/$C7                         {          ADD    DI,AX                         ; cycle := cycle + shortdelta}
  401.   /$3B/$BE/>LONGDELTA              {          CMP    DI,>LongDelta[BP]             ; is cycle >= long delta???}
  402.   /$7C/$08                         {          JL     PL9                           ; no, skip (don't move along x AXis yet)}
  403.   /$2B/$BE/>LONGDELTA              {          SUB    DI,>LongDelta[BP]             ; yes, reset cycle pointer}
  404.   /$03/$8E/>SHORTSTEP              {          ADD    CX,>ShortStep[BP]             ;        and bump x coordinate}
  405.                                    {PL9:}
  406.   /$46                             {          INC    SI                            ; bump dot counter}
  407.   /$3B/$B6/>LINESTOP               {          CMP    SI,>LineStop[BP]              ; done???}
  408.   /$76/$D4                         {          JBE    AltLoop                       ; no, plot next dot}
  409.   /$E9/$3A/$00                     {          JMP    PLExit                        ; yes, go to common exit}
  410.                                    {;}
  411.                                    {PlotDot:  ;PROC   Near}
  412.                                    {;}
  413.                                    {;  Check if we are to use BIOS to plot pixel}
  414.                                    {;}
  415.   /$F6/$06/>WRITE_SCREEN_MEMORY/$01{         TEST    Byte [>Write_Screen_Memory],1 ;Check if direct scren writes}
  416.   /$74/$2B                         {         JZ      Bios                       ;No -- use BIOS}
  417.                                    {;}
  418.                                    {;  Write pixel directly to screen memory}
  419.                                    {;}
  420.   /$8D/$1E/>SCAN_LINE_TABLE        {         LEA     BX,[>Scan_Line_Table] ; Get scan line table address}
  421.   /$D1/$E2                         {         SHL     DX,1                  ; Y * 2 for integer offset}
  422.   /$01/$D3                         {         ADD     BX,DX                 ; Get offset of entry for Y}
  423.   /$2E/$8B/$1F                     {     CS: MOV     BX,[BX]               ; Get offset for Y}
  424.                                    {;}
  425.   /$89/$CA                         {         MOV     DX,CX                 ; Get X}
  426.   /$89/$C8                         {         MOV     AX,CX}
  427.   /$B1/$03                         {         MOV     CL,3                  ;}
  428.   /$D3/$EA                         {         SHR     DX,CL                 ; X DIV 8 = Byte offset within row}
  429.   /$01/$D3                         {         ADD     BX,DX                 ; Byte location in screen memory}
  430.   /$25/$07/$00                     {         AND     AX,7                  ; X MOD 8}
  431.   /$BA/$80/$00                     {         MOV     DX,$80                ; 1 bit in leftmost position}
  432.   /$89/$C1                         {         MOV     CX,AX                 ; shift count}
  433.   /$D3/$EA                         {         SHR     DX,CL                 ; 1 bit in proper position}
  434.   /$C4/$3E/>GRAPHICS_SCREEN        {         LES     DI,[>Graphics_Screen] ; Get screen address}
  435.   /$01/$DF                         {         ADD     DI,BX                 ; Get byte address}
  436.   /$26/$08/$15                     {     ES: OR      BYTE PTR [DI],DL      ; Get byte to alter}
  437.   /$E9/$07/$00                     {         JMP     Exit                  ; Return to caller}
  438.                                    {;}
  439.                                    {;  Plot pixel using BIOS}
  440.                                    {;}
  441.   /$55                             {Bios:    PUSH    BP                    ; Save BP in case BIOS zaps it}
  442.   /$B8/$01/$0C                     {         MOV     AX,$0C01              ; Plot pixel function}
  443.   /$CD/$10                         {         INT     $10                   ; Plot the pixel via BIOS}
  444.   /$5D                             {         POP     BP                    ; Restore BP}
  445.                                    {;}
  446.                                    {Exit:}
  447.   /$C3                             {         RET}
  448.                                    {;}
  449.                                    {PLExit:}
  450. );
  451.                                    (* Restore timesharing mode *)
  452.  
  453.    IF ( MultiTasker = DoubleDos ) THEN
  454.       TurnOnTimeSharing;
  455.  
  456. END   (* Draw_Line *);
  457.  
  458. (*----------------------------------------------------------------------*)
  459. (*          Plot_Char --- Interpret current char as text to display     *)
  460. (*----------------------------------------------------------------------*)
  461.  
  462. PROCEDURE Plot_Char( Ch: CHAR; X: INTEGER; Y: INTEGER );
  463.  
  464. VAR
  465.    I         : INTEGER;
  466.    K1        : INTEGER;
  467.    K2        : INTEGER;
  468.    XB        : INTEGER;
  469.    XO        : INTEGER;
  470.    XO1       : INTEGER;
  471.    XS        : INTEGER;
  472.    XSL       : INTEGER;
  473.    Do_XOR    : BOOLEAN;
  474.                                    (* Holds point plot routine offset *)
  475. (* STRUCTURED *) CONST
  476.    Point_Plot_Addr : INTEGER = 0;
  477.  
  478.                                    (* Shape table for characters *)
  479. (* STRUCTURED *) CONST
  480.    Char_Bits_Table: ARRAY[0..581] OF BYTE =
  481.                     (     0,   0,   0,   0,   0,   0,
  482.                           0,  96,   0,  96,  96,  96,
  483.                           0,   0,   0,   0, 216, 216,
  484.                           0,  80, 248,  80, 248,  80,
  485.                           0, 240,  40, 112, 160, 120,
  486.                           0, 152,  88,  32, 208, 200,
  487.                           0,  16, 120, 144, 144, 112,
  488.                           0,   0,   0,  32,  48,  48,
  489.                           0,  32,  64,  64,  64,  32,
  490.                           0,  64,  32,  32,  32,  64,
  491.                           0, 136,  80, 248,  80, 136,
  492.                           0,  32,  32, 248,  32,  32,
  493.                           0,  64,  96,   0,   0,   0,
  494.                           0,   0,   0, 240,   0,   0,
  495.                           0,  24,  24,   0,   0,   0,
  496.                           0, 128,  64,  32,  16,   8,
  497.                           0, 112, 136, 168, 136, 112,
  498.                           0, 112,  32,  32,  96,  32,
  499.                           0, 248,  96,  16, 136, 112,
  500.                           0, 112, 136,  48, 136, 112,
  501.                           0,  16, 248, 144,  80,  32,
  502.                           0, 240,   8, 240, 128, 248,
  503.                           0, 112, 136, 240, 128, 112,
  504.                           0,  64,  32,  16,   8, 120,
  505.                           0, 112, 136, 112, 136, 112,
  506.                           0, 112,   8, 120, 136, 112,
  507.                           0,  96,  96,   0,  96,  96,
  508.                           0,  64,  96,   0,  96,  96,
  509.                           0,  16,  32,  64,  32,  16,
  510.                           0,   0, 240,   0, 240,   0,
  511.                           0,  64,  32,  16,  32,  64,
  512.                           0,  32,  32,  48, 136, 112,
  513.                           0, 112, 128, 176, 136, 112,
  514.                           0, 136, 248, 136,  80,  32,
  515.                           0, 240, 136, 240, 136, 240,
  516.                           0, 120, 128, 128, 128, 120,
  517.                           0, 240, 136, 136, 136, 240,
  518.                           0, 248, 128, 240, 128, 248,
  519.                           0, 128, 128, 240, 128, 248,
  520.                           0, 120, 136, 184, 128, 120,
  521.                           0, 136, 136, 248, 136, 136,
  522.                           0, 112,  32,  32,  32, 112,
  523.                           0, 112, 136,   8,   8,   8,
  524.                           0, 136, 144, 224, 144, 136,
  525.                           0, 248, 128, 128, 128, 128,
  526.                           0, 136, 136, 168, 216, 136,
  527.                           0, 136, 152, 168, 200, 136,
  528.                           0, 112, 136, 136, 136, 112,
  529.                           0, 128, 128, 240, 136, 240,
  530.                           0, 104, 152, 168, 136, 112,
  531.                           0, 152, 144, 240, 136, 240,
  532.                           0, 240,   8, 112, 128, 120,
  533.                           0,  32,  32,  32,  32, 248,
  534.                           0, 112, 136, 136, 136, 136,
  535.                           0,  32, 112, 136, 136, 136,
  536.                           0, 136, 216, 168, 136, 136,
  537.                           0, 136,  80,  32,  80, 136,
  538.                           0,  32,  32,  32,  80, 136,
  539.                           0, 248,  64,  32,  16, 248,
  540.                           0, 120,  96,  96,  96, 120,
  541.                           0,   8,  16,  32,  64, 128,
  542.                           0, 120,  24,  24,  24, 120,
  543.                           0,   0,   0, 136,  80,  32,
  544.                           0,   0, 248,   0,   0,   0,
  545.                           0,   0,   0,  32,  96,  96,
  546.                           0, 136, 248, 136,  80,  32,
  547.                           0, 240, 136, 240, 136, 240,
  548.                           0, 120, 128, 128, 128, 120,
  549.                           0, 240, 136, 136, 136, 240,
  550.                           0, 248, 128, 240, 128, 248,
  551.                           0, 128, 128, 240, 128, 248,
  552.                           0, 120, 136, 184, 128, 120,
  553.                           0, 136, 136, 248, 136, 136,
  554.                           0, 112,  32,  32,  32, 112,
  555.                           0, 112, 136,   8,   8,   8,
  556.                           0, 136, 144, 224, 144, 136,
  557.                           0, 248, 128, 128, 128, 128,
  558.                           0, 136, 136, 168, 216, 136,
  559.                           0, 136, 152, 168, 200, 136,
  560.                           0, 112, 136, 136, 136, 112,
  561.                           0, 128, 128, 240, 136, 240,
  562.                           0, 104, 152, 168, 136, 112,
  563.                           0, 152, 144, 240, 136, 240,
  564.                           0, 240,   8, 112, 128, 120,
  565.                           0,  32,  32,  32,  32, 248,
  566.                           0, 112, 136, 136, 136, 136,
  567.                           0,  32, 112, 136, 136, 136,
  568.                           0, 136, 216, 168, 136, 136,
  569.                           0, 136,  80,  32,  80, 136,
  570.                           0,  32,  32,  32,  80, 136,
  571.                           0, 248,  64,  32,  16, 248,
  572.                           0,   0,   0,   0,   0,   0,
  573.                           0,   0,   0,   0,   0,   0,
  574.                           0,   0,   0,   0,   0,   0,
  575.                           0,   0,   0,   0,   0,   0,
  576.                           0,   0,   0,   0,   0,   0,
  577.                           0, 124, 124, 124, 124, 124 );
  578.  
  579. BEGIN (* Plot_Char *)
  580.                                    (* Use XOR rather than OR for *)
  581.                                    (* the cursor.                *)
  582.    Do_XOR := ( ORD( Ch ) = 128 );
  583.  
  584.    IF Write_Screen_Memory THEN
  585.       BEGIN
  586.                                    (* Turn off timesharing while drawing *)
  587.  
  588.          IF ( MultiTasker = DoubleDos ) THEN
  589.             BEGIN
  590.                TurnOffTimeSharing;
  591.                Get_Screen_Address( Graphics_Screen );
  592.             END;
  593.                                    (* Get byte offset in row *)
  594.          XB  := SUCC( X SHR 3 );
  595.                                    (* Get bit offset within byte *)
  596.          XS  := X AND 7;
  597.          XSL := 8 - XS;
  598.                                    (* Get offset of character bit *)
  599.                                    (* pattern.                    *)
  600.  
  601.          K1  := ( ORD( Ch ) - 32 ) * 6;
  602.          K2  := K1 + 5;
  603.  
  604.                                    (* OR/XOR in bits of new character. *)
  605.                                    (* If X is even byte address, then  *)
  606.                                    (* simply loop over rows in the     *)
  607.                                    (* character.  If X is not even     *)
  608.                                    (* byte address, we need to store   *)
  609.                                    (* part of pattern in two success-  *)
  610.                                    (* ive bytes.                       *)
  611.  
  612.          IF ( XS = 0 ) THEN
  613.             WITH Graphics_Screen^ DO
  614.                FOR I := K1 TO K2 DO
  615.                   BEGIN
  616.                      XO := Scan_Line_Table[ Y ] + XB;
  617.                      IF Do_XOR THEN
  618.                         Screen_Image[ XO ] := Screen_Image[ XO ] XOR
  619.                                               Char_Bits_Table[ I ]
  620.                      ELSE
  621.                         Screen_Image[ XO ] := Screen_Image[ XO ] OR
  622.                                               Char_Bits_Table[ I ];
  623.                      Y := PRED( Y );
  624.                   END
  625.          ELSE
  626.             WITH Graphics_Screen^ DO
  627.                FOR I := K1 TO K2 DO
  628.                   BEGIN
  629.                      XO  := Scan_Line_Table[ Y ] + XB;
  630.                      XO1 := SUCC( XO );
  631.                      IF Do_XOR THEN
  632.                         BEGIN
  633.                            Screen_Image[ XO  ] := Screen_Image[ XO  ] XOR
  634.                                                   ( Char_Bits_Table[ I ] SHR XS );
  635.                            Screen_Image[ XO1 ] := Screen_Image[ XO1 ] XOR
  636.                                                   ( Char_Bits_Table[ I ] SHL XSL );
  637.                         END
  638.                      ELSE
  639.                         BEGIN
  640.                            Screen_Image[ XO  ] := Screen_Image[ XO  ] OR
  641.                                                   ( Char_Bits_Table[ I ] SHR XS );
  642.                            Screen_Image[ XO1 ] := Screen_Image[ XO1 ] OR
  643.                                                   ( Char_Bits_Table[ I ] SHL XSL );
  644.                         END;
  645.                      Y := PRED( Y );
  646.                   END;
  647.  
  648.                                    (* Restore timesharing mode *)
  649.  
  650.          IF ( MultiTasker = DoubleDos ) THEN
  651.             TurnOnTimeSharing;
  652.  
  653.       END
  654.    ELSE
  655.       BEGIN (* Plot through BIOS the hard way *)
  656.  
  657.          IF Do_XOR THEN
  658.             Point_Plot_Addr := OFS( XOR_Plot_Point )
  659.          ELSE
  660.             Point_Plot_Addr := OFS( Plot_Point );
  661.  
  662.          INLINE(
  663.   $8B/$86/>X                   {         MOV     AX,[BP+>X]                 ;Get X position}
  664.   /$48                         {         DEC     AX                         ;Decrement for 0 offset later}
  665.   /$89/$C6                     {         MOV     SI,AX                      ;Save X position}
  666.                                {;}
  667.   /$8B/$86/>Y                  {         MOV     AX,[BP+>Y]                 ;Get Y position}
  668.   /$89/$C7                     {         MOV     DI,AX                      ;Save Y position}
  669.                                {;}
  670.   /$31/$C0                     {         XOR     AX,AX                      ;Clear AX}
  671.   /$8A/$46/<CH                 {         MOV     AL,[BP+<Ch]                ;Pick up character to display}
  672.   /$2D/$20/$00                 {         SUB     AX,32                      ;Convert to 0 offset}
  673.   /$89/$C3                     {         MOV     BX,AX}
  674.   /$D1/$E0                     {         SHL     AX,1                       ;Offset * 2}
  675.   /$D1/$E0                     {         SHL     AX,1                       ;Offset * 4}
  676.   /$01/$D8                     {         ADD     AX,BX                      ;Offset * 5}
  677.   /$01/$C3                     {         ADD     BX,AX                      ;Offset * 6 = offset into shape table}
  678.   /$8D/$06/>CHAR_BITS_TABLE    {         LEA     AX,[<Char_Bits_Table]      ;Get address of shape table}
  679.   /$01/$C3                     {         ADD     BX,AX                      ;Get starting address this character}
  680.                                {;}
  681.   /$B9/$06/$00                 {         MOV     CX,6                       ;Loop over rows in character}
  682.                                {;}
  683.   /$51                         {Char1:   PUSH    CX                         ;Save loop counter for rows}
  684.   /$53                         {         PUSH    BX                         ;Save table offset}
  685.                                {;}
  686.   /$2E/$8A/$07                 {    CS:  MOV     AL,[BX]                    ;Get bit pattern for this row}
  687.   /$08/$C0                     {         OR      AL,AL                      ;Check if any bits on in this row}
  688.   /$74/$20                     {         JZ      Char4                      ;No -- skip display this row}
  689.                                {;}
  690.   /$B9/$08/$00                 {         MOV     CX,8                       ;Loop over bits this row}
  691.                                {;}
  692.   /$51                         {Char2:   PUSH    CX                         ;Save loop counter for bits}
  693.                                {;}
  694.   /$A8/$01                     {         TEST    AL,1                       ;See if "this" bit is turned on}
  695.   /$74/$13                     {         JZ      Char3                      ;No -- skip to next bit}
  696.                                {;}
  697.   /$50                         {         PUSH    AX                         ;Save bit mask}
  698.   /$56                         {         PUSH    SI                         ;Save X}
  699.   /$57                         {         PUSH    DI                         ;Save Y}
  700.                                {;}
  701.   /$89/$F0                     {         MOV     AX,SI                      ;Get X}
  702.   /$01/$C8                     {         ADD     AX,CX                      ;Add offset}
  703.   /$50                         {         PUSH    AX                         ;X + offset}
  704.   /$57                         {         PUSH    DI                         ;Y}
  705.   /$2E/$8B/$1E/>POINT_PLOT_ADDR{    CS:  MOV     BX,[>Point_Plot_Addr]      ;Pick up subroutine address}
  706.   /$FF/$D3                     {         CALL    BX                         ;Call point plot routine}
  707.                                {;}
  708.   /$5F                         {         POP     DI                         ;Restore Y}
  709.   /$5E                         {         POP     SI                         ;Restore X}
  710.   /$58                         {         POP     AX                         ;Restore bit mask}
  711.                                {;}
  712.   /$D0/$E8                     {Char3:   SHR     AL,1                       ;Shift bit mask to next bit}
  713.   /$59                         {         POP     CX                         ;Retrieve bits counter}
  714.   /$E2/$E3                     {         LOOP    Char2                      ;and try next bit}
  715.                                {;}
  716.   /$5B                         {Char4:   POP     BX                         ;Retrieve table offset}
  717.   /$43                         {         INC     BX                         ;Point to next shape table byte}
  718.   /$89/$F8                     {         MOV     AX,DI                      ;Decrement Y}
  719.   /$48                         {         DEC     AX                         ;  ...}
  720.   /$89/$C7                     {         MOV     DI,AX                      ;  ...}
  721.   /$59                         {         POP     CX                         ;Retrieve rows counter}
  722.   /$E2/$CD                     {         LOOP    Char1                      ;and try next row}
  723.          );
  724.  
  725.       END;
  726.  
  727. END   (* Plot_Char *);
  728.  
  729. (*----------------------------------------------------------------------*)
  730. (*               Display_Cursor  --- Display block cursor               *)
  731. (*----------------------------------------------------------------------*)
  732.  
  733. PROCEDURE Display_Cursor( X, Y: INTEGER );
  734.  
  735. BEGIN (* Display_Cursor *)
  736.                                    (* Don't display cursor while plotting *)
  737.  
  738.    IF ( FlagG = Text_Plot ) THEN
  739.       Plot_Char( CHR( 128 ) , X , Y );
  740.  
  741. END   (* Display_Cursor *);
  742.  
  743. (*----------------------------------------------------------------------*)
  744. (*           Display_Graphics --- show character received from port     *)
  745. (*----------------------------------------------------------------------*)
  746.  
  747. PROCEDURE Display_Graphics( VAR Ch : CHAR );
  748.  
  749. (*----------------------------------------------------------------------*)
  750. (*                                                                      *)
  751. (*     Procedure:  Display_Graphics                                     *)
  752. (*                                                                      *)
  753. (*     Purpose:    Displays character received from comm. port on       *)
  754. (*                 screen/printer/capture file.                         *)
  755. (*                                                                      *)
  756. (*     Calling Sequence:                                                *)
  757. (*                                                                      *)
  758. (*        Display_Graphics( Ch : CHAR );                                *)
  759. (*                                                                      *)
  760. (*           Ch         --- Character received from Comm. port.         *)
  761. (*                                                                      *)
  762. (*      Calls:   Async_Receive                                          *)
  763. (*               Min                                                    *)
  764. (*               Update_Review_Pointers                                 *)
  765. (*               TimeOfDay                                              *)
  766. (*               TimeDiff                                               *)
  767. (*                                                                      *)
  768. (*      Remarks:                                                        *)
  769. (*                                                                      *)
  770. (*         This routine strips out certain characters which             *)
  771. (*         should not be displayed, implements the XON/XOFF protocol    *)
  772. (*         in a simple-minded manner, performs output wrap, and saves   *)
  773. (*         output line in the review the review buffer.                 *)
  774. (*                                                                      *)
  775. (*----------------------------------------------------------------------*)
  776.  
  777.  
  778. (* STRUCTURED *) CONST
  779.    CR_Ch   : CHAR = ^M;
  780.    LF_Ch   : CHAR = ^J;
  781.    BL_Ch   : CHAR = ' ';
  782.  
  783. VAR
  784.    I    : INTEGER;
  785.    L    : INTEGER;
  786.    Xpos : INTEGER;
  787.    Ypos : INTEGER;
  788.    C    : INTEGER;
  789.    KeyC : CHAR;
  790.  
  791. (*----------------------------------------------------------------------*)
  792. (*          Do_Graphics --- Interpret current char as graphics command  *)
  793. (*----------------------------------------------------------------------*)
  794.  
  795. PROCEDURE Do_Graphics;
  796.  
  797. BEGIN (* Do_Graphics *)
  798.                                    (* Get previous character and *)
  799.                                    (* save current character     *)
  800.    Old     := ORD( Prev_Ch );
  801.    Prev_Ch := Ch;
  802.                                    (* Set first X corrdinate     *)
  803.  
  804.    IF ( C > 31 ) AND ( C < 64 ) AND ( Old > 95 ) AND ( Old < 128 ) THEN
  805.       BEGIN
  806.          Hx      := C;
  807.          EXIT;
  808.       END;
  809.                                    (* Set first Y coordinate     *)
  810.  
  811.    IF ( C > 31 ) AND ( C < 64 ) THEN
  812.       BEGIN
  813.          Hy      := C;
  814.          EXIT;
  815.       END;
  816.                                    (* Set second Y coordinate    *)
  817.  
  818.    IF ( C > 95 ) AND ( C < 128 ) THEN
  819.       BEGIN
  820.          Ly      := C;
  821.          EXIT;
  822.       END;
  823.                                    (* Set second X coordinate, and *)
  824.                                    (* plot point if necessary.     *)
  825.  
  826.    IF ( C > 63 ) AND ( C < 96 ) THEN
  827.       BEGIN
  828.  
  829.          Lx      := C;
  830.                                    (* Get PC screen position of point *)
  831.  
  832.          XPos    := TRUNC( XFactor * ( ( Hx - 32 ) * 32 + Lx - 64 ));
  833.          YPos    := YMax - TRUNC( YFactor * ( ( Hy - 32 ) * 32 + Ly - 96 ));
  834.  
  835.                                    (* Turn off timesharing while drawing *)
  836.  
  837.          IF ( MultiTasker = DoubleDos ) THEN
  838.             BEGIN
  839.                TurnOffTimeSharing;
  840.                Get_Screen_Address( Graphics_Screen );
  841.             END;
  842.                                    (* First coordinate -- just move *)
  843.                                    (* to it                         *)
  844.  
  845.          CASE FlagG OF
  846.             Vector_Plot      : Draw_Line( Graphics_XPos, Graphics_YPos,
  847.                                           XPos, YPos );
  848.             Vector_Plot_Start: FlagG   := Vector_Plot;
  849.             Point_Plot       : Plot_Point( XPos, YPos );
  850.             Point_Plot_Start : FlagG   := Point_Plot;
  851.             ELSE;
  852.          END (* CASE *);
  853.  
  854.                                    (* Restore timesharing mode *)
  855.  
  856.          IF ( MultiTasker = DoubleDos ) THEN
  857.             TurnOnTimeSharing;
  858.                                    (* Update graphics position *)
  859.          Graphics_XPos := XPos;
  860.          Graphics_YPos := YPos;
  861.  
  862.       END;
  863.  
  864. END   (* Do_Graphics *);
  865.  
  866.